﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

using Microsoft.Xna.Framework.Content.Pipeline;
using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
using Microsoft.Xna.Framework.Content.Pipeline.Processors;

using Resources = Rockfan.Framework.Properties.Resources;

namespace Rockfan.Framework.Graphics
{
    public sealed class FretboardEffect : Effect
    {
        #region Properties

        public float Alpha
        {
            get { return _Alpha; }
            set
            {
                var oldValue = Alpha;
                _Alpha = value;

                if (Alpha != oldValue)
                    AlphaParameter.SetValue(_Alpha);
            }
        }

        public Matrix World
        {
            get { return _World; }
            set
            {
                var oldValue = World;
                _World = value;

                if (World != oldValue)
                    WorldParameter.SetValue(World);
            }
        }

        public Matrix View
        {
            get { return _View; }
            set
            {
                var oldValue = View;
                _View = value;

                if (View != oldValue)
                    ViewParameter.SetValue(View);
            }
        }

        public Matrix Projection
        {
            get { return _Projection; }
            set
            {
                var oldValue = Projection;
                _Projection = value;

                if (Projection != oldValue)
                    ProjectionParameter.SetValue(Projection);
            }
        }

        public Texture2D Texture
        {
            get { return _Texture; }
            set
            {
                var oldValue = Texture;
                _Texture = value;

                if (Texture != oldValue)
                    TextureParameter.SetValue(Texture);
            }
        }

        #endregion

        public FretboardEffect(GraphicsDevice device)
            : base(device, GetEffectCode("FretboardEffect.fx"))
        {
            ViewParameter = base.Parameters["View"];
            WorldParameter = base.Parameters["World"];
            ProjectionParameter = base.Parameters["Projection"];

            AlphaParameter = base.Parameters["Alpha"];
            TextureParameter = base.Parameters["Texture"];

            Alpha = 1.0f;
            View = Matrix.Identity;
            World = Matrix.Identity;
            Projection = Matrix.Identity;
            Texture = null;
        }

        private static byte[] GetEffectCode(string xnbFile)
        {
            var spriteEffectCode = Encoding.ASCII.GetString(xnbFile == "FretboardEffect.fx" ? Resources.FretboardEffect : Resources.SpriteEffect);
            EffectContent effectSource = new EffectContent() { EffectCode = spriteEffectCode, Identity = new ContentIdentity { SourceFilename = xnbFile } };
            EffectProcessor effectProcessor = new EffectProcessor();
            CompiledEffectContent content = effectProcessor.Process(effectSource, new EffectProcessorContext());

            return content.GetEffectCode();
        }

        private EffectParameter ViewParameter;
        private EffectParameter WorldParameter;
        private EffectParameter AlphaParameter;
        private EffectParameter TextureParameter;
        private EffectParameter ProjectionParameter;

        private float _Alpha;
        private Matrix _World;
        private Matrix _View;
        private Matrix _Projection;
        private Texture2D _Texture;
    }
}
